using MediatR;
using RBAC.Domain.SmartHealthcare.Hosiptial;
using RBAC.ErrorCode;
using RBAC.Interstructrue;
using RBAC.Interstructrue.Base;
using SmartHealthcare.Write.Api.Application.Command.HospitalExpense;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace SmartHealthcare.Write.Api.Application.Handler.HospitalExpense
{
    /// <summary>
    /// 推送住院费用通知处理器
    /// </summary>
    public class PushExpenseNotificationHandler : IRequestHandler<PushExpenseNotificationCommand, APIResult<bool>>
    {
        private readonly IBaseRepository<HospitalExpenseModel> expenseRepository;
        private readonly IBaseRepository<PatientListModel> patientRepository;
        private readonly RBACDbContext dbContext;
        private readonly ILogger<PushExpenseNotificationHandler> logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="expenseRepository">住院费用记录仓储</param>
        /// <param name="patientRepository">患者信息仓储</param>
        /// <param name="dbContext">数据库上下文</param>
        /// <param name="logger">日志记录器</param>
        public PushExpenseNotificationHandler(
            IBaseRepository<HospitalExpenseModel> expenseRepository,
            IBaseRepository<PatientListModel> patientRepository,
            RBACDbContext dbContext,
            ILogger<PushExpenseNotificationHandler> logger)
        {
            this.expenseRepository = expenseRepository;
            this.patientRepository = patientRepository;
            this.dbContext = dbContext;
            this.logger = logger;
        }

        /// <summary>
        /// 处理推送住院费用通知请求
        /// </summary>
        /// <param name="request">请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>推送结果</returns>
        public Task<APIResult<bool>> Handle(PushExpenseNotificationCommand request, CancellationToken cancellationToken)
        {
            APIResult<bool> result = new APIResult<bool>();

            try
            {
                logger.LogInformation($"开始推送住院费用通知，费用ID：{request.ExpenseId}，病人卡号：{request.MedicalCard}，住院登记ID：{request.InpatientRegistryId}");

                // 参数验证
                if (!request.ExpenseId.HasValue && string.IsNullOrWhiteSpace(request.MedicalCard) && !request.InpatientRegistryId.HasValue)
                {
                    result.Code = APIEnums.Fail;
                    result.Msg = "费用ID、病人卡号和住院登记ID不能同时为空";
                    return Task.FromResult(result);
                }

                // 查询需要推送的费用记录
                List<HospitalExpenseModel> expensesToPush;

                if (request.ExpenseId.HasValue)
                {
                    // 推送单条费用记录
                    var expense = expenseRepository.GetALL()
                        .Where(e => e.Id == request.ExpenseId.Value && e.IsDeleted == false)
                        .FirstOrDefault();

                    if (expense == null)
                    {
                        result.Code = APIEnums.Fail;
                        result.Msg = "未找到指定ID的费用记录";
                        return Task.FromResult(result);
                    }

                    expensesToPush = new List<HospitalExpenseModel> { expense };
                }
                else
                {
                    // 构建查询条件
                    var query = expenseRepository.GetALL()
                        .Where(e => e.IsDeleted == false && e.IsPushedToPatient == false);

                    if (!string.IsNullOrWhiteSpace(request.MedicalCard))
                    {
                        query = query.Where(e => e.MedicalCard == request.MedicalCard);
                    }

                    if (request.InpatientRegistryId.HasValue)
                    {
                        query = query.Where(e => e.InpatientRegistryId == request.InpatientRegistryId.Value);
                    }

                    if (request.ExpenseDate.HasValue)
                    {
                        var startDate = request.ExpenseDate.Value.Date;
                        var endDate = startDate.AddDays(1);
                        query = query.Where(e => e.ExpenseTime >= startDate && e.ExpenseTime < endDate);
                    }

                    expensesToPush = query.ToList();

                    if (expensesToPush.Count == 0)
                    {
                        result.Code = APIEnums.Success;
                        result.Msg = "没有需要推送的费用记录";
                        result.Data = true;
                        return Task.FromResult(result);
                    }
                }

                // 开始事务
                using (var transaction = dbContext.Database.BeginTransaction())
                {
                    try
                    {
                        // 更新推送状态
                        foreach (var expense in expensesToPush)
                        {
                            expense.IsPushedToPatient = true;
                            expense.PushTime = DateTime.Now;

                            expenseRepository.Update(expense);
                            
                            // 这里可以添加实际的推送逻辑，如发送短信、推送APP消息等
                            // 模拟推送操作
                            logger.LogInformation($"向患者 {expense.PatientName} 推送费用通知：{expense.ItemName}，金额：{expense.TotalAmount}元");
                        }

                        // 提交事务
                        transaction.Commit();

                        result.Code = APIEnums.Success;
                        result.Msg = $"成功推送 {expensesToPush.Count} 条费用记录";
                        result.Data = true;

                        logger.LogInformation($"费用推送成功，共推送 {expensesToPush.Count} 条记录");
                    }
                    catch (Exception ex)
                    {
                        // 回滚事务
                        transaction.Rollback();
                        throw ex;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "推送住院费用通知时发生异常");
                result.Code = APIEnums.Error;
                result.Msg = "推送费用通知时发生异常：" + ex.Message;
                result.Data = false;
            }

            return Task.FromResult(result);
        }
    }
} 